﻿using System;

namespace Mono.Cecil.PE
{
	// Token: 0x020000ED RID: 237
	internal class ByteBuffer
	{
		// Token: 0x06000982 RID: 2434 RVA: 0x00005764 File Offset: 0x00003964
		public ByteBuffer()
		{
			this.buffer = Empty<byte>.Array;
		}

		// Token: 0x06000983 RID: 2435 RVA: 0x00005779 File Offset: 0x00003979
		public ByteBuffer(int length)
		{
			this.buffer = new byte[length];
		}

		// Token: 0x06000984 RID: 2436 RVA: 0x0000578F File Offset: 0x0000398F
		public ByteBuffer(byte[] buffer)
		{
			this.buffer = (buffer ?? Empty<byte>.Array);
			this.length = this.buffer.Length;
		}

		// Token: 0x06000985 RID: 2437 RVA: 0x000057B7 File Offset: 0x000039B7
		public void Advance(int length)
		{
			this.position += length;
		}

		// Token: 0x06000986 RID: 2438 RVA: 0x0002A430 File Offset: 0x00028630
		public byte ReadByte()
		{
			byte[] array = this.buffer;
			int num = this.position;
			this.position = num + 1;
			return array[num];
		}

		// Token: 0x06000987 RID: 2439 RVA: 0x0002A45C File Offset: 0x0002865C
		public sbyte ReadSByte()
		{
			return (sbyte)this.ReadByte();
		}

		// Token: 0x06000988 RID: 2440 RVA: 0x0002A478 File Offset: 0x00028678
		public byte[] ReadBytes(int length)
		{
			byte[] array = new byte[length];
			Buffer.BlockCopy(this.buffer, this.position, array, 0, length);
			this.position += length;
			return array;
		}

		// Token: 0x06000989 RID: 2441 RVA: 0x0002A4B8 File Offset: 0x000286B8
		public ushort ReadUInt16()
		{
			ushort result = (ushort)((int)this.buffer[this.position] | (int)this.buffer[this.position + 1] << 8);
			this.position += 2;
			return result;
		}

		// Token: 0x0600098A RID: 2442 RVA: 0x0002A4FC File Offset: 0x000286FC
		public short ReadInt16()
		{
			return (short)this.ReadUInt16();
		}

		// Token: 0x0600098B RID: 2443 RVA: 0x0002A518 File Offset: 0x00028718
		public uint ReadUInt32()
		{
			uint result = (uint)((int)this.buffer[this.position] | (int)this.buffer[this.position + 1] << 8 | (int)this.buffer[this.position + 2] << 16 | (int)this.buffer[this.position + 3] << 24);
			this.position += 4;
			return result;
		}

		// Token: 0x0600098C RID: 2444 RVA: 0x0002A580 File Offset: 0x00028780
		public int ReadInt32()
		{
			return (int)this.ReadUInt32();
		}

		// Token: 0x0600098D RID: 2445 RVA: 0x0002A598 File Offset: 0x00028798
		public ulong ReadUInt64()
		{
			uint num = this.ReadUInt32();
			uint num2 = this.ReadUInt32();
			return (ulong)num2 << 32 | (ulong)num;
		}

		// Token: 0x0600098E RID: 2446 RVA: 0x0002A5C0 File Offset: 0x000287C0
		public long ReadInt64()
		{
			return (long)this.ReadUInt64();
		}

		// Token: 0x0600098F RID: 2447 RVA: 0x0002A5D8 File Offset: 0x000287D8
		public uint ReadCompressedUInt32()
		{
			byte b = this.ReadByte();
			bool flag = (b & 128) == 0;
			uint result;
			if (flag)
			{
				result = (uint)b;
			}
			else
			{
				bool flag2 = (b & 64) == 0;
				if (flag2)
				{
					result = (((uint)b & 4294967167U) << 8 | (uint)this.ReadByte());
				}
				else
				{
					result = (uint)(((int)b & -193) << 24 | (int)this.ReadByte() << 16 | (int)this.ReadByte() << 8 | (int)this.ReadByte());
				}
			}
			return result;
		}

		// Token: 0x06000990 RID: 2448 RVA: 0x0002A648 File Offset: 0x00028848
		public int ReadCompressedInt32()
		{
			byte b = this.buffer[this.position];
			int num = (int)this.ReadCompressedUInt32();
			int num2 = num >> 1;
			bool flag = (num & 1) == 0;
			int result;
			if (flag)
			{
				result = num2;
			}
			else
			{
				int num3 = (int)(b & 192);
				int num4 = num3;
				if (num4 != 0 && num4 != 64)
				{
					if (num4 != 128)
					{
						result = num2 - 268435456;
					}
					else
					{
						result = num2 - 8192;
					}
				}
				else
				{
					result = num2 - 64;
				}
			}
			return result;
		}

		// Token: 0x06000991 RID: 2449 RVA: 0x0002A6C4 File Offset: 0x000288C4
		public float ReadSingle()
		{
			bool flag = !BitConverter.IsLittleEndian;
			float result;
			if (flag)
			{
				byte[] array = this.ReadBytes(4);
				Array.Reverse(array);
				result = BitConverter.ToSingle(array, 0);
			}
			else
			{
				float num = BitConverter.ToSingle(this.buffer, this.position);
				this.position += 4;
				result = num;
			}
			return result;
		}

		// Token: 0x06000992 RID: 2450 RVA: 0x0002A720 File Offset: 0x00028920
		public double ReadDouble()
		{
			bool flag = !BitConverter.IsLittleEndian;
			double result;
			if (flag)
			{
				byte[] array = this.ReadBytes(8);
				Array.Reverse(array);
				result = BitConverter.ToDouble(array, 0);
			}
			else
			{
				double num = BitConverter.ToDouble(this.buffer, this.position);
				this.position += 8;
				result = num;
			}
			return result;
		}

		// Token: 0x06000993 RID: 2451 RVA: 0x0002A77C File Offset: 0x0002897C
		public void WriteByte(byte value)
		{
			bool flag = this.position == this.buffer.Length;
			if (flag)
			{
				this.Grow(1);
			}
			byte[] array = this.buffer;
			int num = this.position;
			this.position = num + 1;
			array[num] = value;
			bool flag2 = this.position > this.length;
			if (flag2)
			{
				this.length = this.position;
			}
		}

		// Token: 0x06000994 RID: 2452 RVA: 0x000032C3 File Offset: 0x000014C3
		public void WriteSByte(sbyte value)
		{
			this.WriteByte((byte)value);
		}

		// Token: 0x06000995 RID: 2453 RVA: 0x0002A7E0 File Offset: 0x000289E0
		public void WriteUInt16(ushort value)
		{
			bool flag = this.position + 2 > this.buffer.Length;
			if (flag)
			{
				this.Grow(2);
			}
			byte[] array = this.buffer;
			int num = this.position;
			this.position = num + 1;
			array[num] = (byte)value;
			byte[] array2 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array2[num] = (byte)(value >> 8);
			bool flag2 = this.position > this.length;
			if (flag2)
			{
				this.length = this.position;
			}
		}

		// Token: 0x06000996 RID: 2454 RVA: 0x000057C8 File Offset: 0x000039C8
		public void WriteInt16(short value)
		{
			this.WriteUInt16((ushort)value);
		}

		// Token: 0x06000997 RID: 2455 RVA: 0x0002A860 File Offset: 0x00028A60
		public void WriteUInt32(uint value)
		{
			bool flag = this.position + 4 > this.buffer.Length;
			if (flag)
			{
				this.Grow(4);
			}
			byte[] array = this.buffer;
			int num = this.position;
			this.position = num + 1;
			array[num] = (byte)value;
			byte[] array2 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array2[num] = (byte)(value >> 8);
			byte[] array3 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array3[num] = (byte)(value >> 16);
			byte[] array4 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array4[num] = (byte)(value >> 24);
			bool flag2 = this.position > this.length;
			if (flag2)
			{
				this.length = this.position;
			}
		}

		// Token: 0x06000998 RID: 2456 RVA: 0x000057D4 File Offset: 0x000039D4
		public void WriteInt32(int value)
		{
			this.WriteUInt32((uint)value);
		}

		// Token: 0x06000999 RID: 2457 RVA: 0x0002A91C File Offset: 0x00028B1C
		public void WriteUInt64(ulong value)
		{
			bool flag = this.position + 8 > this.buffer.Length;
			if (flag)
			{
				this.Grow(8);
			}
			byte[] array = this.buffer;
			int num = this.position;
			this.position = num + 1;
			array[num] = (byte)value;
			byte[] array2 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array2[num] = (byte)(value >> 8);
			byte[] array3 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array3[num] = (byte)(value >> 16);
			byte[] array4 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array4[num] = (byte)(value >> 24);
			byte[] array5 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array5[num] = (byte)(value >> 32);
			byte[] array6 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array6[num] = (byte)(value >> 40);
			byte[] array7 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array7[num] = (byte)(value >> 48);
			byte[] array8 = this.buffer;
			num = this.position;
			this.position = num + 1;
			array8[num] = (byte)(value >> 56);
			bool flag2 = this.position > this.length;
			if (flag2)
			{
				this.length = this.position;
			}
		}

		// Token: 0x0600099A RID: 2458 RVA: 0x000057DF File Offset: 0x000039DF
		public void WriteInt64(long value)
		{
			this.WriteUInt64((ulong)value);
		}

		// Token: 0x0600099B RID: 2459 RVA: 0x0002AA4C File Offset: 0x00028C4C
		public void WriteCompressedUInt32(uint value)
		{
			bool flag = value < 128U;
			if (flag)
			{
				this.WriteByte((byte)value);
			}
			else
			{
				bool flag2 = value < 16384U;
				if (flag2)
				{
					this.WriteByte((byte)(128U | value >> 8));
					this.WriteByte((byte)(value & 255U));
				}
				else
				{
					this.WriteByte((byte)(value >> 24 | 192U));
					this.WriteByte((byte)(value >> 16 & 255U));
					this.WriteByte((byte)(value >> 8 & 255U));
					this.WriteByte((byte)(value & 255U));
				}
			}
		}

		// Token: 0x0600099C RID: 2460 RVA: 0x0002AAE8 File Offset: 0x00028CE8
		public void WriteCompressedInt32(int value)
		{
			bool flag = value >= 0;
			if (flag)
			{
				this.WriteCompressedUInt32((uint)((uint)value << 1));
			}
			else
			{
				bool flag2 = value > -64;
				if (flag2)
				{
					value = 64 + value;
				}
				else
				{
					bool flag3 = value >= -8192;
					if (flag3)
					{
						value = 8192 + value;
					}
					else
					{
						bool flag4 = value >= -536870912;
						if (flag4)
						{
							value = 536870912 + value;
						}
					}
				}
				this.WriteCompressedUInt32((uint)(value << 1 | 1));
			}
		}

		// Token: 0x0600099D RID: 2461 RVA: 0x0002AB60 File Offset: 0x00028D60
		public void WriteBytes(byte[] bytes)
		{
			int num = bytes.Length;
			bool flag = this.position + num > this.buffer.Length;
			if (flag)
			{
				this.Grow(num);
			}
			Buffer.BlockCopy(bytes, 0, this.buffer, this.position, num);
			this.position += num;
			bool flag2 = this.position > this.length;
			if (flag2)
			{
				this.length = this.position;
			}
		}

		// Token: 0x0600099E RID: 2462 RVA: 0x0002ABD4 File Offset: 0x00028DD4
		public void WriteBytes(int length)
		{
			bool flag = this.position + length > this.buffer.Length;
			if (flag)
			{
				this.Grow(length);
			}
			this.position += length;
			bool flag2 = this.position > this.length;
			if (flag2)
			{
				this.length = this.position;
			}
		}

		// Token: 0x0600099F RID: 2463 RVA: 0x0002AC2C File Offset: 0x00028E2C
		public void WriteBytes(ByteBuffer buffer)
		{
			bool flag = this.position + buffer.length > this.buffer.Length;
			if (flag)
			{
				this.Grow(buffer.length);
			}
			Buffer.BlockCopy(buffer.buffer, 0, this.buffer, this.position, buffer.length);
			this.position += buffer.length;
			bool flag2 = this.position > this.length;
			if (flag2)
			{
				this.length = this.position;
			}
		}

		// Token: 0x060009A0 RID: 2464 RVA: 0x0002ACB4 File Offset: 0x00028EB4
		public void WriteSingle(float value)
		{
			byte[] bytes = BitConverter.GetBytes(value);
			bool flag = !BitConverter.IsLittleEndian;
			if (flag)
			{
				Array.Reverse(bytes);
			}
			this.WriteBytes(bytes);
		}

		// Token: 0x060009A1 RID: 2465 RVA: 0x0002ACE4 File Offset: 0x00028EE4
		public void WriteDouble(double value)
		{
			byte[] bytes = BitConverter.GetBytes(value);
			bool flag = !BitConverter.IsLittleEndian;
			if (flag)
			{
				Array.Reverse(bytes);
			}
			this.WriteBytes(bytes);
		}

		// Token: 0x060009A2 RID: 2466 RVA: 0x0002AD14 File Offset: 0x00028F14
		private void Grow(int desired)
		{
			byte[] array = this.buffer;
			int num = array.Length;
			byte[] dst = new byte[Math.Max(num + desired, num * 2)];
			Buffer.BlockCopy(array, 0, dst, 0, num);
			this.buffer = dst;
		}

		// Token: 0x040003C3 RID: 963
		internal byte[] buffer;

		// Token: 0x040003C4 RID: 964
		internal int length;

		// Token: 0x040003C5 RID: 965
		internal int position;
	}
}
